<template>
  <div class="dom-handle" v-loading="loading">
    <div class="handle-box">
      <el-form label-width="120px" :inline="false" size="normal">
        <el-row :gutter="20">
          <el-col :span="12">
            <p class="title">DOM切片</p>
            <el-form-item label="输入路径">
              <el-input v-model="inputPath" size="mini" style="width: calc(100% - 50px)" disabled></el-input>
              <el-button size="mini" @click="openFiles('inputPath')">···</el-button>
            </el-form-item>
            <el-form-item label="输出路径">
              <el-input v-model="outputPath" size="mini" style="width: calc(100% - 50px)" disabled></el-input>
              <el-button size="mini" @click="openFiles('outputPath')">···</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <p class="title">轻量化参数选项</p>
            <el-form-item label="层级设置">
              <el-input v-model.number="startLevel" size="mini" style="width: 45%"></el-input>
              <span style="color: #fff;margin: 0 5px">-</span>
              <el-input v-model.number="endLevel" size="mini" style="width: 45%"></el-input>
            </el-form-item>
            <el-form-item label="压缩格式">
              <el-select v-model="compressedFormat" size="mini">
                <el-option label="png" value="terrain">terrain</el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-progress :text-inside="true" :stroke-width="26" :percentage="percentage" v-show="progressShow"></el-progress>
      <div class="start-processing">
        <el-button type="primary" size="mini" @click="startProcessing">开始处理</el-button>
      </div>
    </div>
    <!-- 输入选择 -->
    <el-dialog title="选择文件夹" :visible.sync="inputFilesShow" width="30%" @close="deselect" :destroy-on-close="true"
      :close-on-click-modal="false" v-loading="loading">
      <div class="file-box" v-loading="fileLoading">
        <el-scrollbar style="height:calc(100% - 30px);">
          <el-tree :props="props" :load="loadImageNode" lazy :expand-on-click-node="false" @node-click="imageSelect">
          </el-tree>
        </el-scrollbar>
        <el-input v-model="folderAddress" size="mini" disabled></el-input>
      </div>
      <span slot="footer">
        <el-button @click="deselect">Cancel</el-button>
        <el-button type="primary" @click="confirmClick">确定</el-button>
      </span>
    </el-dialog>
    <!-- 输出选择 -->
    <el-dialog title="选择文件夹" :visible.sync="fileSelectShow" width="30%" @close="deselect" :destroy-on-close="true"
      :close-on-click-modal="false" v-loading="loading">
      <div class="file-box" v-loading="fileLoading">
        <el-scrollbar style="height:calc(100% - 30px);">
          <el-tree :props="props" :load="loadFileNode" lazy :expand-on-click-node="false" @node-click="selectFile">
          </el-tree>
        </el-scrollbar>
        <el-input v-model="folderAddress" size="mini" disabled></el-input>
      </div>
      <span slot="footer">
        <el-button @click="deselect">取消</el-button>
        <el-button type="primary" @click="definiteSelect">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
export default {
  data () {
    return {
      loading: false,
      timer: null,
      percentage: 0,
      progressShow: false,
      inputPath: '',
      outputPath: '',
      inputFilesShow: false,
      props: {
        label: 'name',
        children: 'children',
        isLeaf: 'leaf'
      },
      fileSelectShow: false,
      fileLoading: false,
      folderAddress: '',
      startLevel: 1,
      endLevel: 20,
      selectNode: null,
      questId: '',
      compressedFormat: "png",
      defaultLevels: [],
      fileGroup: [],
      bestLevels: '',
      cacheConfig: { "needImgCache": false, "imgCacheMode": 1, "imgCacheLevel": [0, 20] },
      center: "POINT(114.36870574951172 35.746421813964844)",
      config: { "images": [], "terrain": false, "bands": [], "srid": 4326, "noDataValue": [], "resampleConfigs": [], "dispelEdgedConfigs": [], "render": [], "grid": "", "programme": 0, "origin": null, "resolutions": null, "styleJson": {}, "imgMap": { "/data/raster/HN_DEM_30m/HN_DEM_30m.tif": { "rasterEditable": { "bandslndex": [1], "bandsIndexNoDataValue": [0] }, "fileSize": 0 } }, "gridUnit": 1 },
    };
  },
  methods: {
    async startProcessing () {
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
      this.defaultLevels = [`${this.startLevel}-${this.endLevel}`]
      if (!this.inputPath || !this.outputPath) {
        this.$message.error("请先选择输入路径和输出路径")
        return
      }
      let usableDataSource = await this.getDataSource()
      this.config.imgMap = {}
      this.config.styleJson = {}
      if (this.fileGroup.length == 0) {
        this.config.images = [
          {
            img: this.selectNode.data.path,
            datasourceId: usableDataSource[0].idString
          }
        ]
        this.config.bands = this.selectNode.data.bands.slice(0, 3)
        this.config.noDataValue = this.selectNode.data.noDataValue.slice(0, 3)
        this.defaultLevels.forEach(item => {
          this.config.styleJson[item] = {
            fileNameList: [this.selectNode.data.path]
          }
        })
        this.config.imgMap[this.selectNode.data.path] = {
          rasterEditable: {
            bandslndex: this.selectNode.data.bands.slice(0, 3),
            bandsIndexNoDataValue: this.selectNode.data.noDataValue.slice(0, 3)
          },
          fileSize: 0
        }
        let x = (this.selectNode.data.bbox[0] + this.selectNode.data.bbox[2]) / 2
        let y = (this.selectNode.data.bbox[1] + this.selectNode.data.bbox[3]) / 2
        // this.center = `POINT(${x} ${y})`
      } else {
        this.config.imgMap = {}
        this.config.styleJson = {}
        this.config.bands = this.fileGroup[0].bands.slice(0, 3)
        this.config.noDataValue = this.fileGroup[0].noDataValue.slice(0, 3)
        let x = (this.fileGroup[0].bbox[0] + this.fileGroup[0].bbox[2]) / 2
        let y = (this.fileGroup[0].bbox[1] + this.fileGroup[0].bbox[3]) / 2
        // this.center = `POINT(${x} ${y})`
        this.fileGroup.forEach(item => {
          this.config.images.push({
            img: item.path,
            datasourceId: usableDataSource[0].idString
          })
          this.config.imgMap[item.path] = {
            rasterEditable: {
              bandslndex: item.bands.slice(0, 3),
              bandsIndexNoDataValue: item.noDataValue.slice(0, 3)
            },
            fileSize: 0
          }
          this.defaultLevels.forEach(level => {
            if (!this.config.styleJson[level]) {
              this.config.styleJson[level] = {
                fileNameList: []
              }
            }
            this.config.styleJson[level].fileNameList.push(item.path)
          })
        })
      }
      let level = Math.ceil((parseInt(this.startLevel) + parseInt(this.endLevel)) / 2)
      let tempService = await axios.post(`${window.mapServerIp}/${window.prefix}/dataservice/createTemp`, {
        config: JSON.stringify(this.config),
        datasourceId: '',
        gridUnit: 1,
        name: '',
        type: 2
      })
      let bbox = await axios.get(`${window.mapServerIp}/rasterserver/image/getServiceBBox/${tempService.data.data}`)
      let x = (bbox.data[0] + bbox.data[2]) / 2
      let y = (bbox.data[1] + bbox.data[3]) / 2
      this.center = `POINT(${x} ${y})`
      let params = {
        cacheConfig: JSON.stringify(this.cacheConfig),
        center: this.center,
        config: JSON.stringify(this.config),
        datasourceId: '',
        groupId: "-2",
        name: "测评DOM_" + new Date().getTime(),
        level: level,
        type: 2
      }
      let res = await axios.post(`${window.mapServerIp}/${window.prefix}/dataservice/register`, [params])
      if (res.data.status == 200) {
        this.getServiceInfo(res.data.data[0])
      } else {
        this.$message.error('转换失败')
      }
    },
    // 获取地形服务详情并存储
    async getServiceInfo (id) {
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/dataservice/getInfo/${id}`)
      let info = res.data.data
      this.questId = info.id
      let params = {
        id: info.id,
        name: info.name,
        info: JSON.stringify(info),
        path: this.outputPath,
        // 0: DEM 1：DOM 
        type: 1
      }
      await axios.post(`${window.nodeApiIp}/saveService/insertDemService`, params)
      let resp = await axios.post(`${window.nodeApiIp}/dataExport/imageExport`, {
        id: info.id,
        name: info.name,
        src: this.outputPath
      })
      if (resp.data.status == 200) {
        this.$message.success(resp.data.msg)
        this.progressShow = true
        this.timer = setInterval(() => {
          axios.get(`${window.nodeApiIp}/saveService/getInfoById?id=${info.id}`).then(res => {
            this.percentage = (parseFloat(res.data[0].scale)).toFixed(2) - 0
            if (res.data[0].scale == '100') {
              clearInterval(this.timer)
              this.timer = null
              this.$message.success('转换成功')
              setTimeout(() => {
                this.$router.go(0)
              }, 2000)
            }
          })
        }, 3000)
      }
    },
    // 获取最优层级
    async getBestLevels (path) {
      let res = await axios.post(`${window.mapServerIp}/rasterserver/raster/getFitLevels`, {
        path: path,
        gridName: "degreebase256tdt"
      })
      this.defaultLevels = []
      let levels = res.data.data.levels
      this.startLevel = levels[0].level
      this.endLevel = levels[levels.length - 1].level
      this.bestLevels = `${levels[0].level}-${levels[levels.length - 1].level}`
      this.defaultLevels.push(this.bestLevels)
    },
    // 获取所有影像服务源并查找符合输入路径的数据源
    async getDataSource () {
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/list?typeCode=0103&page=1&rows=1000`)
      let usableDataSource = res.data.data.records.filter(item => this.inputPath.indexOf(item.config) > -1)
      return usableDataSource
    },
    // 查询数据源中是否存在当前路径，没有的话创建数据源
    async createDataSource (path) {
      let isWindowsPath = /^[A-Za-z]:\\/
      let isLinuxPath = /^\/[^/]+/
      let config = ''
      if (isWindowsPath.test(path)) {
        let arr = path.split('\\')
        arr.forEach((item, index) => {
          if (index < arr.length - 1) {
            config += item + '\\'
          }
        })
      }
      if (isLinuxPath.test(path)) {
        let arr = path.split('/')
        arr.forEach((item, index) => {
          if (index < arr.length - 1) {
            config += item + '/'
          }
        })
      }
      let res = await axios.post(`${window.mapServerIp}/${window.prefix}/datasource/register`, {
        config: config,
        name: "测试" + new Date().getTime(),
        password: "",
        remark: "",
        type: "raster",
        typeCode: "0103",
        user: ""
      })
      if (res.data.status !== 200) {
        this.$message.success('数据创建失败')
      }
    },
    async confirmClick () {
      console.log(this.selectNode.data)
      this.fileGroup = []
      this.inputPath = this.folderAddress
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/list?typeCode=0103&page=1&rows=1000`)
      if (res.data.data.records.length > 0) {
        let usableDataSource = res.data.data.records.some(item => this.inputPath.indexOf(item.config) > -1)
        if (!usableDataSource) {
          await this.createDataSource(this.inputPath)
        }
      } else {
        await this.createDataSource(this.inputPath)
      }
      this.inputFilesShow = false
      if (this.selectNode.data.file) {
        this.getAllImageTif(this.selectNode.path, this.selectNode.data)
        // this.getBestLevels(this.selectNode.path)
        // if (!this.selectNode.data.hasPyramid) {
        //   this.createPyramid([this.selectNode.data.path])
        // }
      } else {
        this.getAllImageTif(this.selectNode.path)
      }
    },
    // 创建金字塔
    // async createPyramid (pathList) {
    //   this.loading = true
    //   await axios.post(`${window.rasterServerIp}/mapserver/raster/pyramid/batch/build`, {
    //     path: pathList
    //   })
    //   this.config.imgMap = {}
    //   this.config.styleJson = {}
    //   this.config.bands = this.fileGroup[0].bands.slice(0, 3)
    //   this.config.noDataValue = this.fileGroup[0].noDataValue.slice(0, 3)
    //   let x = (this.fileGroup[0].bbox[0] + this.fileGroup[0].bbox[2]) / 2
    //   let y = (this.fileGroup[0].bbox[1] + this.fileGroup[0].bbox[3]) / 2
    //   // this.center = `POINT(${x} ${y})`
    //   this.fileGroup.forEach(item => {
    //     this.config.images.push({
    //       img: item.path,
    //       datasourceId: usableDataSource[0].idString
    //     })
    //     this.config.imgMap[item.path] = {
    //       rasterEditable: {
    //         bandslndex: item.bands.slice(0, 3),
    //         bandsIndexNoDataValue: item.noDataValue.slice(0, 3)
    //       },
    //       fileSize: 0
    //     }
    //     this.defaultLevels.forEach(level => {
    //       if (!this.config.styleJson[level]) {
    //         this.config.styleJson[level] = {
    //           fileNameList: []
    //         }
    //       }
    //       this.config.styleJson[level].fileNameList.push(item.path)
    //     })
    //   })
    //   let params = {
    //     config: JSON.stringify(this.config),
    //     datasourceId: '',
    //     gridUnit: 1,
    //     name: '',
    //     type: 2
    //   }
    //   let tempRes = await axios.post(`${window.mapServerIp}/${window.prefix}/dataservice/createTemp`, params)
    //   let fitLevelData = await axios.get(`${window.rasterServerIp}/mapserver/image/getFitLevels/${tempRes.data.data}`)
    //   this.startLevel = fitLevelData.data[0]
    //   this.endLevel = fitLevelData.data[1]
    //   this.defaultLevels = []
    //   this.defaultLevels.push(`${this.startLevel}-${this.endLevel}`)
    //   this.loading = false
    //   return
    //   let requests = []
    //   pathList.forEach(i => {
    //     requests.push(axios.get(`${window.mapServerIp}/${window.prefix}/services/buildPyramid?path=${encodeURIComponent(i)}`))
    //   })
    //   let quests = await Promise.all(requests)
    //   // 获取创建金字塔任务id
    //   let questIds = []
    //   quests.forEach(m => {
    //     questIds.push(m.data.data)
    //   })
    //   let exist = await this.getQuests(questIds)
    //   if (exist) {
    //     let timer = setInterval(async () => {
    //       exist = await this.getQuests(questIds)
    //       if (!exist) {
    //         clearInterval(timer)
    //         this.loading = false
    //       }
    //     }, 2000)
    //   } else {
    //     this.loading = false
    //   }
    // },
    // 获取正在进行的任务，查看对应id的任务是否都完成
    async getQuests (ids) {
      let exist = false
      let quests = await axios.get(`${window.mapServerIp}/${window.prefix}/services/task-list?status=1`)
      for (let i = 0; i < quests.data.data.records.length; i++) {
        let quest = quests.data.data.records[i]
        let exist = ids.some(id => id == quest.id)
        if (exist) {
          return exist
        }
      }
      return exist
    },
    imageSelect (row) {
      this.selectNode = row
      this.folderAddress = row.path
    },
    // 获取文件夹下所有tif文件，并找到整体的最优层级
    async getAllImageTif (path, data) {
      this.loading = true
      this.fileGroup = []
      let pathList = []
      if (data) {
        if (!data.hasPyramid) {
          pathList.push(path)
        }
        this.fileGroup.push(data)
      } else {
        let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/getImageFile?path=${encodeURIComponent(path)}&rows=10000`)
        res.data.data.list.forEach(item => {
          if (item.file) {
            if (!item.hasPyramid) {
              pathList.push(item.path)
            }
            this.fileGroup.push(item)
          }
        })
      }

      if (pathList.length > 0) {
        await axios.post(`${window.rasterServerIp}/mapserver/raster/pyramid/batch/build`, {
          path: pathList
        })
      }
      let usableDataSource = await this.getDataSource()
      this.config.imgMap = {}
      this.config.styleJson = {}
      this.config.bands = this.fileGroup[0].bands.slice(0, 3)
      this.config.noDataValue = this.fileGroup[0].noDataValue.slice(0, 3)
      let x = (this.fileGroup[0].bbox[0] + this.fileGroup[0].bbox[2]) / 2
      let y = (this.fileGroup[0].bbox[1] + this.fileGroup[0].bbox[3]) / 2
      // this.center = `POINT(${x} ${y})`
      this.fileGroup.forEach(item => {
        this.config.images.push({
          img: item.path,
          datasourceId: usableDataSource[0].idString
        })
        this.config.imgMap[item.path] = {
          rasterEditable: {
            bandslndex: item.bands.slice(0, 3),
            bandsIndexNoDataValue: item.noDataValue.slice(0, 3)
          },
          fileSize: 0
        }
        this.defaultLevels.forEach(level => {
          if (!this.config.styleJson[level]) {
            this.config.styleJson[level] = {
              fileNameList: []
            }
          }
          this.config.styleJson[level].fileNameList.push(item.path)
        })
      })
      let params = {
        config: JSON.stringify(this.config),
        datasourceId: '',
        gridUnit: 1,
        name: '',
        type: 2
      }
      let tempRes = await axios.post(`${window.mapServerIp}/${window.prefix}/dataservice/createTemp`, params)
      let fitLevelData = await axios.get(`${window.rasterServerIp}/mapserver/image/getFitLevels/${tempRes.data.data}`)
      this.startLevel = fitLevelData.data[0]
      this.endLevel = fitLevelData.data[1]
      this.defaultLevels = []
      this.defaultLevels.push(`${this.startLevel}-${this.endLevel}`)
      this.loading = false
    },
    openFiles (field) {
      this.folderAddress = ""
      if (field == 'inputPath') {
        this.inputFilesShow = true
      } else {
        this.fileSelectShow = true
      }
    },
    deselect () {
      this.inputFilesShow = false
      this.fileSelectShow = false
    },
    // 获取输入路径
    async loadImageNode (node, resolve) {
      let path = ""
      if (node.data) {
        path = node.data.path
      }
      const hasSpace = /\s/.test(path);
      if (hasSpace) {
        this.$message.warning('路径中不能包含空格')
        return resolve([])
      } else {
        let records = await this.getImageDirectory(encodeURIComponent(path))
        // if (!path) {
        //   this.getDataSourceByPath(records)
        // }
        return resolve(records)
      }
    },
    // 获取影像文件夹
    async getImageDirectory (path = '') {
      this.loading = true
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/getImageFile?path=${path}&rows=10000`)
      this.loading = false
      if (res.data.data.list.length > 0) {
        let fileList = []
        res.data.data.list.forEach(item => {
          let ob = {
            name: item.name,
            path: item.path,
            children: [],
            data: item,
            leaf: item.file
          }
          fileList.push(ob)
        })
        return fileList
      } else {
        return []
      }
    },
    // 获取输出路径
    async loadFileNode (node, resolve) {
      if (node.level === 0) {
        let records = await this.getDisk()
        return resolve(records)
      } else {
        let path = this.getPathFromTree(node)
        let records = await this.getDirectory(path)
        if (records) {
          return resolve(records)
        } else {
          node.data.leaf = true
          return resolve([])
        }
      }
    },
    // 从树中获取到文件路径
    getPathFromTree (node) {
      let path = ''
      if (node.parent.data) {
        let parentPath = this.getPathFromTree(node.parent)
        path = parentPath + node.data.name + "\\"
      } else {
        path = node.data.name + ":\\"
      }
      return path
    },
    // 获取盘符
    async getDisk () {
      this.fileLoading = true
      let res = await axios.get(`${window.nodeApiIp}/directory/driveLetters`)
      this.fileLoading = false
      let fileList = []
      res.data.forEach(item => {
        let ob = {
          name: item,
          children: [],
          leaf: false
        }
        fileList.push(ob)
      })
      return fileList
    },
    // 获取文件夹
    async getDirectory (path) {
      let res = await axios.post(`${window.nodeApiIp}/directory/getDirectory`, {
        path: path
      })
      if (res.data.directory.length > 0) {
        let fileList = []
        res.data.directory.forEach(item => {
          let ob = {
            name: item.name,
            children: [],
            leaf: false
          }
          fileList.push(ob)
        })
        return fileList
      } else {
        return false
      }
    },
    // 获取文件夹地址
    selectFile (data, node) {
      let path = this.getPathFromTree(node)
      this.folderAddress = path
    },
    definiteSelect () {
      this.fileSelectShow = false
      this.outputPath = this.folderAddress
    }
  },
  created () { },
  mounted () { }
};
</script>
<style lang="less">
.dom-handle {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  .handle-box {
    width: 1200px;
    background: #1A1A1A;
    padding: 10px 30px;
    box-sizing: border-box;
    background: rgba(4, 11, 20, 0.63);
    border: 1px solid rgba(22, 93, 202, 0.6);
    border-radius: 10px;

    .title {
      color: #fff;
    }

    .el-form-item__label {
      color: #fff
    }

    .footer {
      width: 100%;
      height: 50px;
      display: flex;
      justify-content: end;
      align-items: center;
    }

    .start-processing {
      width: 100%;
      height: 40px;
      display: flex;
      justify-content: end;
      align-items: center;
    }
  }

  .file-box {
    width: 100%;
    height: 400px
  }
}
</style>